package com.smartbone.dao.daoImplemetation;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import javax.persistence.Query;

import org.springframework.context.ApplicationContext;
import org.springframework.orm.jpa.JpaCallback;
import org.springframework.orm.jpa.support.JpaDaoSupport;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.smartbone.dao.daoInterface.IUsersDAO;
import com.smartbone.entity.Users;

/**
 * A data access object (DAO) providing persistence and search support for Users
 * entities. Transaction control of the save(), update() and delete() operations
 * can directly support Spring container-managed transactions or they can be
 * augmented to handle user-managed Spring transactions. Each of these methods
 * provides additional information for how to configure it for the desired type
 * of transaction control.
 * 
 * @see com.Users
 * @author MyEclipse Persistence Tools
 */

public class UsersDAO extends JpaDaoSupport implements IUsersDAO {
	// property constants
	public static final String TYPE = "type";
	public static final String USERNAME = "username";
	public static final String PASSWORD = "password";
	public static final String USERNAME_CN = "usernameCn";
	public static final String TELPHONE = "telphone";
	public static final String MOBILE = "mobile";
	public static final String MAIL = "mail";
	public static final String AREA = "area";
	public static final String ADDRESS = "address";
	public static final String ENABLED = "enabled";
	public static final String ACCOUNT_NON_EXPIRED = "accountNonExpired";
	public static final String ACCOUNT_NON_LOCKED = "accountNonLocked";
	public static final String CREDENTIALS_NON_EXPIRED = "credentialsNonExpired";

	/**
	 * Perform an initial save of a previously unsaved Users entity. All
	 * subsequent persist actions of this entity should use the #update()
	 * method. This operation must be performed within the a database
	 * transaction context for the entity's data to be permanently saved to the
	 * persistence store, i.e., database. This method uses the
	 * {@link javax.persistence.EntityManager#persist(Object)
	 * EntityManager#persist} operation.
	 * <p>
	 * User-managed Spring transaction example:
	 * 
	 * <pre>
	 * TransactionStatus txn = txManager
	 * 		.getTransaction(new DefaultTransactionDefinition());
	 * UsersDAO.save(entity);
	 * txManager.commit(txn);
	 * </pre>
	 * 
	 * @see <a href =
	 *      "http://www.myeclipseide.com/documentation/quickstarts/jpaspring#containermanaged">Spring
	 *      container-managed transaction examples</a>
	 * @param entity
	 *            Users entity to persist
	 * @throws RuntimeException
	 *             when the operation fails
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void save(Users entity) {
		logger.info("saving Users instance");
		try {
			getJpaTemplate().persist(entity);
			logger.info("save successful");
		} catch (RuntimeException re) {
			logger.error("save failed", re);
			throw re;
		}
	}

	/**
	 * Delete a persistent Users entity. This operation must be performed within
	 * the a database transaction context for the entity's data to be
	 * permanently deleted from the persistence store, i.e., database. This
	 * method uses the {@link javax.persistence.EntityManager#remove(Object)
	 * EntityManager#delete} operation.
	 * <p>
	 * User-managed Spring transaction example:
	 * 
	 * <pre>
	 * TransactionStatus txn = txManager
	 * 		.getTransaction(new DefaultTransactionDefinition());
	 * UsersDAO.delete(entity);
	 * txManager.commit(txn);
	 * entity = null;
	 * </pre>
	 * 
	 * @see <a href =
	 *      "http://www.myeclipseide.com/documentation/quickstarts/jpaspring#containermanaged">Spring
	 *      container-managed transaction examples</a>
	 * @param entity
	 *            Users entity to delete
	 * @throws RuntimeException
	 *             when the operation fails
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void delete(Users entity) {
		logger.info("deleting Users instance");
		try {
			entity = getJpaTemplate().getReference(Users.class, entity.getId());
			getJpaTemplate().remove(entity);
			logger.info("delete successful");
		} catch (RuntimeException re) {
			logger.error("delete failed", re);
			throw re;
		}
	}

	/**
	 * Persist a previously saved Users entity and return it or a copy of it to
	 * the sender. A copy of the Users entity parameter is returned when the JPA
	 * persistence mechanism has not previously been tracking the updated
	 * entity. This operation must be performed within the a database
	 * transaction context for the entity's data to be permanently saved to the
	 * persistence store, i.e., database. This method uses the
	 * {@link javax.persistence.EntityManager#merge(Object) EntityManager#merge}
	 * operation.
	 * <p>
	 * User-managed Spring transaction example:
	 * 
	 * <pre>
	 * TransactionStatus txn = txManager
	 * 		.getTransaction(new DefaultTransactionDefinition());
	 * entity = UsersDAO.update(entity);
	 * txManager.commit(txn);
	 * </pre>
	 * 
	 * @see <a href =
	 *      "http://www.myeclipseide.com/documentation/quickstarts/jpaspring#containermanaged">Spring
	 *      container-managed transaction examples</a>
	 * @param entity
	 *            Users entity to update
	 * @return Users the persisted Users entity instance, may not be the same
	 * @throws RuntimeException
	 *             if the operation fails
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public Users update(Users entity) {
		logger.info("updating Users instance");
		try {
			Users result = getJpaTemplate().merge(entity);
			logger.info("update successful");
			return result;
		} catch (RuntimeException re) {
			logger.error("update failed", re);
			throw re;
		}
	}

	public Users findById(Integer id) {
		logger.info("finding Users instance with id: " + id);
		try {
			Users instance = getJpaTemplate().find(Users.class, id);
			return instance;
		} catch (RuntimeException re) {
			logger.error("find failed", re);
			throw re;
		}
	}

	/**
	 * Find all Users entities with a specific property value.
	 * 
	 * @param propertyName
	 *            the name of the Users property to query
	 * @param value
	 *            the property value to match
	 * @return List<Users> found by query
	 */
	@SuppressWarnings("unchecked")
	public List<Users> findByProperty(String propertyName, final Object value) {
		logger.info("finding Users instance with property: " + propertyName
				+ ", value: " + value);
		try {
			final String queryString = "select model from Users model where model."
					+ propertyName + "= :propertyValue";
			return getJpaTemplate().executeFind(new JpaCallback() {
				public Object doInJpa(EntityManager em)
						throws PersistenceException {
					Query query = em.createQuery(queryString);
					query.setParameter("propertyValue", value);
					return query.getResultList();
				}
			});
		} catch (RuntimeException re) {
			logger.error("find by property name failed", re);
			throw re;
		}
	}

	public List<Users> findByType(Object type) {
		return findByProperty(TYPE, type);
	}

	public List<Users> findByUsername(Object username) {
		return findByProperty(USERNAME, username);
	}

	public List<Users> findByPassword(Object password) {
		return findByProperty(PASSWORD, password);
	}

	public List<Users> findByUsernameCn(Object usernameCn) {
		return findByProperty(USERNAME_CN, usernameCn);
	}

	public List<Users> findByTelphone(Object telphone) {
		return findByProperty(TELPHONE, telphone);
	}

	public List<Users> findByMobile(Object mobile) {
		return findByProperty(MOBILE, mobile);
	}

	public List<Users> findByMail(Object mail) {
		return findByProperty(MAIL, mail);
	}

	public List<Users> findByArea(Object area) {
		return findByProperty(AREA, area);
	}

	public List<Users> findByAddress(Object address) {
		return findByProperty(ADDRESS, address);
	}

	public List<Users> findByEnabled(Object enabled) {
		return findByProperty(ENABLED, enabled);
	}

	public List<Users> findByAccountNonExpired(Object accountNonExpired) {
		return findByProperty(ACCOUNT_NON_EXPIRED, accountNonExpired);
	}

	public List<Users> findByAccountNonLocked(Object accountNonLocked) {
		return findByProperty(ACCOUNT_NON_LOCKED, accountNonLocked);
	}

	public List<Users> findByCredentialsNonExpired(Object credentialsNonExpired) {
		return findByProperty(CREDENTIALS_NON_EXPIRED, credentialsNonExpired);
	}

	/**
	 * Find all Users entities.
	 * 
	 * @return List<Users> all Users entities
	 */
	@SuppressWarnings("unchecked")
	public List<Users> findAll() {
		logger.info("finding all Users instances");
		try {
			final String queryString = "select model from Users model";
			return getJpaTemplate().executeFind(new JpaCallback() {
				public Object doInJpa(EntityManager em)
						throws PersistenceException {
					Query query = em.createQuery(queryString);
					return query.getResultList();
				}
			});
		} catch (RuntimeException re) {
			logger.error("find all failed", re);
			throw re;
		}
	}

	public static IUsersDAO getFromApplicationContext(ApplicationContext ctx) {
		return (IUsersDAO) ctx.getBean("UsersDAO");
	}
	
	@SuppressWarnings("unchecked")
	public List<Users> findAllWithPageSize(int startRowPara, int pageSizePara) {
		logger.info("finding all Users instances");
		try {
			
			final String queryString = "select model from Users model";
			final int startRow = startRowPara;
			final int pageSize = pageSizePara;
			return getJpaTemplate().executeFind(new JpaCallback() {
				public Object doInJpa(EntityManager em)
						throws PersistenceException {
					Query query = em.createQuery(queryString);
					query.setFirstResult(startRow);
					query.setMaxResults(pageSize);
					return query.getResultList();
				}
			});
			
		} catch (RuntimeException re) {
			logger.error("find all failed", re);
			throw re;
		}
	}

	public String findAllUserCount() {
		logger.info("finding all Users instances");
		try {
			final String queryString = "select count(model) from Users model";
			Object countObject = getJpaTemplate().find(queryString).get(0);
			String count = "0";
			if (countObject != null) {
				count = countObject.toString();
			}
			return count;
		} catch (RuntimeException re) {
			logger.error("find count failed", re);
			throw re;
		}
	}
}